package com.ctl.jvm;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * <p>Title: SavePointTest</p>
 * <p>Description: </p>
 * <p>Copyright: Copyright (c) 2019</p>
 * <p>Company: www.ctl.com</p>
 *
 * @author ctl
 * @version 1.1
 * @date 2023-01-31 15:57
 */
public class SavePointTest {
    public static AtomicInteger num = new AtomicInteger(0);

    public static void main(String[] args) throws InterruptedException {
        Runnable runnable = () -> {
//            for (int i = 0; i < 1000000000; i++) {
            for (int i = 0; i < 100000000; i++) {
                num.getAndAdd(1);
            }
            System.out.println(Thread.currentThread().getName() + "执行结束!");
        };
        Thread t1 = new Thread(runnable);
        Thread t2 = new Thread(runnable);
        t1.start();
        t2.start();
        Thread.sleep(1000);
        System.out.println("num = " + num);
    }
}
//jdk8 num一定两次循环的总数
//Thread-1执行结束!
//Thread-0执行结束!
//num = 20000000
//是 HotSpot 虚拟机为了避免安全点过多带来过重的负担，对循环还有一项优化措施，认为循环次数较少的话，执行时间应该也不会太长，
//所以使用 int 类型或范围更小的数据类型作为索引值的循环默认是不会被放置安全点的。这种循环被称为可数循环（Counted Loop），
// 相对应地，使用 long 或者范围更大的数据类型作为索引值的循环就被称为不可数循环（Uncounted Loop），将会被放置安全点。

//jdk17,jdk11 num不是两次循环的总数
//num = 111603165
//Thread-0执行结束!
//Thread-1执行结束!